package org.urchr.beorganized.mobile.base.network;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import org.urchr.beorganized.mobile.base.MobileSession;
import org.w3c.dom.Element;

public class XMLRequest {

	private String apiURL = null;
	
//	public static void setApiURL(String url){
//		apiURL = ((url.startsWith("http://") || url.startsWith("https://"))?"":"http://")+
//				url+(url.endsWith("/")?"api/":"/api/");
//	}
//	
	
	private String operation = null;
	private Map<String, String> params = new HashMap<String, String>();
	
	public XMLRequest(String operation){
		this(operation, MobileSession.getSession().getToken(), MobileSession.getSession().getServer());
	}
	
	public XMLRequest(String operation, String token, String apiURL){
		this.operation = operation;
		this.apiURL = apiURL;
		if(null!=token)
			addParameter("token", token);
	}
	
	public void addParameter(String name, String value){
		if(null==value)
			return;
		params.put(name, value);
	}
	
	public void addParameter(String name, int value){
		params.put(name, ""+value);
	}
	
	public Element callOperation() throws NetworkException{
		try {
			HttpURLConnection conn = (HttpURLConnection) new URL(apiURL+operation).openConnection();
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setAllowUserInteraction(false);
			conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			conn.setUseCaches(false);
			DataOutputStream outputStream = new DataOutputStream(conn.getOutputStream());
			boolean firstKeyWritten = false;
			StringBuffer query = new StringBuffer("");
			for (String key : params.keySet()) {
				String value = params.get(key);
				if(null!=value){
					if(firstKeyWritten)
						query.append("&");
					query.append(key+"="+URLEncoder.encode(value, "utf-8"));
					
					firstKeyWritten = true;
				}
			}
			outputStream.writeBytes(query.toString());
			outputStream.flush();
			outputStream.close();
			
			XMLDocumentBuilder doc = new XMLDocumentBuilder();
			if(!doc.readXML(conn.getInputStream())){
				throw new NetworkException("Invalid response from server received. Please try again");
			}else{
				if("error".equals(doc.getRootElement().getNodeName())){
					String errorDesc = "Unknown error received. It is strange";
					String errorCode = doc.getRootElement().getTextContent();
					if("DB_ERROR".equals(errorCode))
						errorDesc = "Database error, please try again";
					if("INVALID_END_DATE".equals(errorCode))
						errorDesc = "Invalid event end date provided. Please check entered data";
					if("INVALID_NAME".equals(errorCode))
						errorDesc = "Invalid name provided. This field is required";
					if("INVALID_START_DATE".equals(errorCode))
						errorDesc = "Invalid event start date. Please check entered data";
					if("INVALID_URL".equals(errorCode))
						errorDesc = "Invalid URL provided. This field is required";
					if("INVALID_USER_PASS".equals(errorCode))
						errorDesc = "Invalid user name or password";
					if("NO_PERMISSION".equals(errorCode))
						errorDesc = "You have no permission for this operation. Please check that someone granted you sufficient permissions";
					if("START_DATE_LESS_END_DATE".equals(errorCode))
						errorDesc = "Event finish date is earlier than start date. Please provide correct dates";
					if("URL_TOO_LONG".equals(errorCode))
						errorDesc = "URL is too long. Maximum length is 255 characters";
//					if("".equals(errorCode))
//						errorDesc = "";
					
					throw new NetworkException(errorDesc);
				}
				return doc.getRootElement();
			}
		} catch (Exception e) {
			e.printStackTrace();
			if(e instanceof NetworkException)
				throw (NetworkException)e;
			throw new NetworkException("Connection to server failed. Server is not responding");
		}
	}
}
